package jehc.djshi.workflow.web;

import com.github.pagehelper.PageInfo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import jehc.djshi.common.annotation.Auth;
import jehc.djshi.common.base.BaseAction;
import jehc.djshi.common.base.BasePage;
import jehc.djshi.common.base.BaseResult;
import jehc.djshi.common.base.BaseSearch;
import jehc.djshi.workflow.model.ActRuExecution;
import jehc.djshi.workflow.service.ActRuExecutionService;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
 * @Desc 执行实例
 * @Author 邓纯杰
 * @CreateTime 2012-12-12 12:12:12
 */
@Api(value = "执行实例", description = "执行实例",tags = "执行实例" )
@RestController
@RequestMapping("/actRuExecution")
public class ActRuExecutionController extends BaseAction {

    @Resource
    private ActRuExecutionService actRuExecutionService;

    private static final String PARENTID="PARENTID";
    private static final String INSTID = "INSTID";
    private static final String DEFID = "DEFID";

    /**
     * 查询并分页
     * @param baseSearch
     */
    @ApiOperation(value="查询并分页", notes="查询并分页")
    @PostMapping(value="/list")
    @Auth(value = "/actRuExecution/list",authenticationType = Auth.AuthorizationType.REQUIRED_LOGIN_NOT_AUTH)
    public BasePage<List<ActRuExecution>> getActRuExecutionListByCondition(@RequestBody(required=true)BaseSearch baseSearch){
        Map<String, Object> condition = baseSearch.convert();
        commonHPager(baseSearch);
        List<ActRuExecution> actRuExecutionList = actRuExecutionService.getActRuExecutionListByCondition(condition);
        doRowSpan(actRuExecutionList);
        PageInfo<ActRuExecution> page = new PageInfo<ActRuExecution>(actRuExecutionList);
        return outPageBootStr(page,baseSearch);
    }
    /**
     * 查询单条记录
     * @param id
     */
    @ApiOperation(value="查询单条记录", notes="查询单条记录")
    @GetMapping(value="/get/{id}")
    @Auth(value = "/actRuExecution/get",authenticationType = Auth.AuthorizationType.REQUIRED_LOGIN_NOT_AUTH)
    public BaseResult<ActRuExecution> getActRuExecutionById(@PathVariable("id")String id){
        ActRuExecution actRuExecution = actRuExecutionService.getActRuExecutionById(id);
        return outDataStr(actRuExecution);
    }

    /**
     * 计算合并单元格
     * @param actRuExecutions
     */
    private void doRowSpan(List<ActRuExecution> actRuExecutions) {
        Map<String,Integer> propertyCountMap = countPropertyCount(actRuExecutions);
        List<String> hadGetKeys = new ArrayList<>();
        for(ActRuExecution actRuExecution:actRuExecutions){
            //父节点
            String parentIdKey = PARENTID+actRuExecution.getProcInstId()+actRuExecution.getParentId();
            Integer parentIdCount = propertyCountMap.get(parentIdKey);
            if(parentIdCount == null){
                actRuExecution.setParentIdRowSpan(1);
            }else{
                if(hadGetKeys.contains(parentIdKey)){
                    actRuExecution.setParentIdRowSpan(0); //已取过
                }else{
                    actRuExecution.setParentIdRowSpan(parentIdCount); //第一次取
                    hadGetKeys.add(parentIdKey);
                }
            }

            //流程实例
            String procInstIdKey = INSTID+actRuExecution.getProcInstId();
            Integer procInstIdCount = propertyCountMap.get(procInstIdKey);
            if(procInstIdCount == null){
                actRuExecution.setProcInstIdRowSpan(1);
            }else{
                if(hadGetKeys.contains(procInstIdKey)){
                    actRuExecution.setProcInstIdRowSpan(0); //已取过
                }else{
                    actRuExecution.setProcInstIdRowSpan(procInstIdCount); //第一次取
                    hadGetKeys.add(procInstIdKey);
                }
            }

            //流程定义
            String procDefIdKey = DEFID+actRuExecution.getProcDefId();
            Integer procDefIdCount = propertyCountMap.get(procDefIdKey);
            if(procDefIdCount == null){
                actRuExecution.setProcDefIdRowSpan(1);
            }else {
                if(hadGetKeys.contains(procDefIdKey)){
                    actRuExecution.setProcDefIdRowSpan(0);//已取过
                }else{
                    actRuExecution.setProcDefIdRowSpan(procDefIdCount);//第一次取
                    hadGetKeys.add(procDefIdKey);
                }
            }
        }
    }

    /**
     * 统计每个字段的每组成员个数
     * @param actRuExecutionList 记录
     * @return 每个字段的每组成员个数
     */
    private Map<String,Integer> countPropertyCount(List<ActRuExecution> actRuExecutionList){
        Map<String,Integer> propertyCountMap = new HashMap<>();
        for(ActRuExecution actRuExecution : actRuExecutionList){
            // parentId
            String parentId = PARENTID+actRuExecution.getProcInstId()+actRuExecution.getParentId();
            if(propertyCountMap.get(parentId) == null || null == parentId){
                propertyCountMap.put(parentId,1);
            }else{
                int count = propertyCountMap.get(parentId);
                propertyCountMap.put(parentId,count+1);
            }

            //procInstId
            String procInstId = INSTID+actRuExecution.getProcInstId();
            if(propertyCountMap.get(procInstId) == null || null == procInstId){
                propertyCountMap.put(procInstId,1);
            }else{
                int count = propertyCountMap.get(procInstId);
                propertyCountMap.put(procInstId,count+1);
            }

            // procDefId
            String procDefId = DEFID+actRuExecution.getProcDefId();
            if(propertyCountMap.get(procDefId) == null || null == procDefId){
                propertyCountMap.put(procDefId,1);
            }else{
                int count = propertyCountMap.get(procDefId);
                propertyCountMap.put(procDefId,count+1);
            }
        }
        return propertyCountMap;
    }

    /**
     * 删除运行实例
     * @param id
     */
    @ApiOperation(value="删除运行实例", notes="删除运行实例")
    @DeleteMapping(value="/delete")
    public BaseResult deleteActRuExecution(String id,String procInstId){
        return actRuExecutionService.delActRuExecution(id,procInstId);
    }
}
